import * as CANNON from 'cannon-es';
import * as THREE from 'three';

export class Road {
    private size: number;
    private horizontalSegments: number;
    private verticalSegments: number;
    mesh: THREE.Mesh;

    constructor(size: number, horizontalSegments: number, verticalSegments: number) {
        this.size = size;
        this.horizontalSegments = horizontalSegments;
        this.verticalSegments = verticalSegments;
    }

    // 其他方法和功能可以在这里添加
    init(physicsWorld: CANNON.World) {
        // let w = this.calculateHorizontalSegmentWidth();
        // let h = this.calculateVerticalSegmentHeight();
        let matrix: any[] = [];
        for (let j = 0; j < this.verticalSegments; j++) {
            let ary = [];
            for (let i = 0; i < this.horizontalSegments; i++) {
                ary.push(Math.sin(i) * 0.1 + Math.sin(j) * 0.1);
            }
            matrix.push(ary);
        }
        var hfShape = new CANNON.Heightfield(matrix, {
            elementSize: this.size
        });
        var hfBody = new CANNON.Body({ mass: 0 });
        hfBody.addShape(hfShape);

        // 旋转和移动
        const rotationQuaternion = new CANNON.Quaternion();
        rotationQuaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2); // 绕x轴旋转90度
        hfBody.quaternion.mult(rotationQuaternion, hfBody.quaternion); // 应用旋转

        const movementVector = new CANNON.Vec3(-this.horizontalSegments * this.size * 0.5, -3, this.verticalSegments * this.size * 0.5);
        hfBody.position.vadd(movementVector, hfBody.position); // 应用位移


        this.mesh = new THREE.Mesh(this.createHeightfieldGeometry(hfShape), new THREE.MeshStandardMaterial({
            color: 0x44ff88,
            flatShading: true
        }))

        this.mesh.position.copy(hfBody.position)
        this.mesh.quaternion.copy(hfBody.quaternion)
        // setTimeout(() => {
        // 
        // hfBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
        // hfBody.position.set(-this.horizontalSegments * this.size * 0.5, -3, this.verticalSegments * this.size * 0.5);
        // }, 300)

        physicsWorld.addBody(hfBody);

    }

    createHeightfieldGeometry(shape: CANNON.Heightfield) {
        const geometry = new THREE.BufferGeometry();
        const s = shape.elementSize || 1; // assumes square heightfield, else i*x, j*y

        const positions = shape.data.flatMap((row, i) => row.flatMap((z, j) => [i * s, j * s, z]));
        const indices = [];

        for (let xi = 0; xi < shape.data.length - 1; xi++) {
            for (let yi = 0; yi < shape.data[xi].length - 1; yi++) {
                const stride = shape.data[xi].length;
                const index = xi * stride + yi;
                indices.push(index + 1, index + stride, index + stride + 1);
                indices.push(index + stride, index + 1, index);
            }
        }

        geometry.setIndex(indices);
        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
        geometry.computeBoundingSphere();
        geometry.computeVertexNormals();
        return geometry;
    }

}
